<template>
    <div>
        <!-- 表头分页查询条件， shadow="never" 指定 card 卡片组件没有阴影 -->
        <el-card shadow="never" class="mb-5">
            <!-- flex 布局，内容垂直居中 -->
            <div class="flex items-center">
                <el-text>文章标题</el-text>
                <div class="ml-3 w-52 mr-5">
                    <el-input v-model="searchArticleName" placeholder="请输入（模糊查询）" />
                </div>

                <el-text>创建日期</el-text>
                <div class="ml-3 w-30 mr-5">
                    <!-- 日期选择组件（区间选择） -->
                    <el-date-picker v-model="pickDate" type="daterange" range-separator="至" start-placeholder="开始时间"
                        end-placeholder="结束时间" size="default" :shortcuts="shortcuts" @change="datepickerChange" />
                </div>

                <el-button type="primary" class="ml-3" :icon="Search" @click="getTableData">查询</el-button>
                <el-button class="ml-3" :icon="RefreshRight" @click="reset">重置</el-button>
            </div>
        </el-card>
        <el-card shadow="never">
            <!-- 新增按钮 -->
            <div class="mb-5 flex items-center">
                <el-button type="primary" @click="isArticlePublishEditorShow = true">
                    <el-icon class="mr-1">
                        <EditPen />
                    </el-icon>
                    写文章</el-button>
            </div>

            <!-- 分页列表 -->
            <el-table :data="tableData" :default-sort="{ prop: 'articleName', order: 'descending' }" border stripe
                style="width: 100%" v-loading="tableLoading">
                <el-table-column type="selection" width="45" />
                <el-table-column type="index" label="序号" width="60" />
                <el-table-column prop="id" label="文章编号" width="180" />
                <el-table-column prop="title" label="文章标题" sortable width="180" />
                <el-table-column prop="cover" label="文章封面" sortable width="180">
                    <template #default="scope">
                        <el-image style="width: 64px;" :src="scope.row.cover" />
                    </template>
                </el-table-column>
                <el-table-column prop="createTime" label="首发时间" width="180" />
                <el-table-column label="文章操作">
                    <template #default="scope">
                        <el-button type="success" size="small" @click="goArticleDetailPage(scope.row.id)">
                            <el-icon class="mr-1">
                                <View />
                            </el-icon>
                            浏览
                        </el-button>

                        <el-button type="primary" size="small" @click="showArticleUpdateEditor(scope.row)">
                            <el-icon class="mr-1">
                                <Edit />
                            </el-icon>
                            修改
                        </el-button>
                        <el-button type="danger" size="small" @click="deleteArticleSubmit(scope.row)">
                            <el-icon class="mr-1">
                                <Delete />
                            </el-icon>
                            删除
                        </el-button>
                    </template>
                </el-table-column>
            </el-table>
            <!-- 分页 -->
            <div class="mt-10 flex justify-center">
                <el-pagination v-model:current-page="current" v-model:page-size="size" :page-sizes="[5, 10, 20, 50]"
                    :small="false" :background="true" layout="total, sizes, prev, pager, next, jumper" :total="total"
                    @size-change="handleSizeChange" @current-change="getTableData" />
            </div>
        </el-card>
        <FormDialog ref="formDialogRef" title="添加标签" destroyOnClose @submit="onSubmit">
            <el-form ref="formRef" :rules="rules" :model="form">
                <el-form-item label="标签名" prop="name" label-width="100px">
                    <!-- 输入框组件 -->
                    <el-input size="large" v-model="form.name" placeholder="请输入标签名(1-16个字符范围内)" maxlength="16"
                        show-word-limit clearable />
                </el-form-item>
            </el-form>
        </FormDialog>

        <FormDialog ref="formDialogPlusRef" title="批量添加标签" destroyOnClose @submit="onPlusSubmit">
            <el-form ref="InputRef" :model="plusForm">
                <el-form-item label="标签集合" prop="name" label-width="120px">
                    <!-- 输入框组件 -->
                    <div class="flex items-center gap-2">
                        <el-tag v-for="article in dynamicArticles" :key="article" closable :disable-transitions="false"
                            type="success" @close="handleClose(article)">
                            {{ article }}
                        </el-tag>

                        <span class="w-20">
                            <el-input v-if="inputVisible" ref="InputRef" v-model="inputValue" class="w-20" size="small"
                                @keyup.enter="handleInputConfirm" @blur="handleInputConfirm" />
                            <el-button v-else class="button-new-tag" size="small" @click="showInput">
                                + 新增标签
                            </el-button>
                        </span>
                    </div>
                </el-form-item>
            </el-form>
        </FormDialog>

        <el-dialog v-model="isArticlePublishEditorShow" :show-close="false" width="500" :fullscreen="true" :close-on-press-escape="false">
            <template #header="{  }">
                <!-- 固钉组件，固钉到顶部 -->
                <el-affix :offset="20" style="width: 100%; margin-bottom: 20px">
                    <!-- 指定 flex 布局， 高度为 10， 背景色为白色 -->
                    <div class="flex h-10 bg-white">
                        <div class="mr-auto flex">
                            <el-button @click="isArticlePublishEditorShow = false" type="warning">
                                <el-icon class="ml-1">
                                    <ArrowLeft />
                                </el-icon>
                                文章管理
                            </el-button>
                        </div>
                        <!-- 字体加粗 -->
                        <h1 class="font-bold" style="justify-items: center; font-size: 20px;">写文章</h1>
                        <!-- 靠右对齐 -->
                        <div class="ml-auto flex">
                            <el-button type="primary" @click="publishArticleSubmit">
                                <el-icon class="mr-1">
                                    <Promotion />
                                </el-icon>
                                发布文章
                            </el-button>
                        </div>
                    </div>
                </el-affix>
            </template>
            <div style="margin-top: 10px;">
                <!-- label-position="top" 用于指定 label 元素在上面 -->
                <el-form :model="form" ref="publishArticleFormRef" label-position="top" size="large" :rules="rules">
                    <el-form-item label="标题" prop="title">
                        <el-input v-model="form.title" autocomplete="off" size="large" maxlength="52" show-word-limit
                            clearable />
                    </el-form-item>
                    <el-form-item label="内容" prop="content">
                        <!-- Markdown 编辑器 -->
                        <MdEditor v-model="form.content" editorId="publishArticleEditor" :previewTheme="mdPreviewTheme"
                            @onUploadImg="onUploadImg" @onSave="onSave" />
                    </el-form-item>
                    <el-form-item label="封面" prop="cover">
                        <el-upload class="avatar-uploader" action="#" :auto-upload="false" :show-file-list="false"
                            :on-change="handleCoverChange">
                            <img v-if="form.cover" :src="form.cover" class="avatar" />
                            <el-icon v-else class="avatar-uploader-icon">
                                <Plus />
                            </el-icon>
                        </el-upload>
                    </el-form-item>
                    <el-form-item label="摘要" prop="summary">
                        <!-- :rows="3" 指定 textarea 默认显示 3 行 -->
                        <el-input v-model="form.summary" :rows="3" type="textarea" placeholder="请输入文章摘要" />
                    </el-form-item>
                    <el-form-item label="分类" prop="categoryId">
                        <el-select v-model="form.categoryId" clearable placeholder="---请选择---" size="large"
                            style="width: 200px;">
                            <el-option v-for="item in categories" :key="item.value" :label="item.label"
                                :value="item.value" />
                        </el-select>
                    </el-form-item>
                    <el-form-item label="标签" prop="tags">
                        <!-- 标签选择 -->
                        <el-select v-model="form.tags" multiple filterable remote reserve-keyword
                            placeholder="---请输入---" remote-show-suffix :remote-method="remoteMethod" allow-create
                            default-first-option :loading="tagSelectLoading" size="large" style="width: 640px;"
                            tag-type="success">
                            <el-option v-for="item in tags" :key="item.value" :label="item.label" :value="item.value" />
                        </el-select>
                    </el-form-item>
                </el-form>
            </div>

        </el-dialog>

        <!-- 编辑博客 -->
        <el-dialog v-model="isArticleUpdateEditorShow" :fullscreen="true" :show-close="false"
            :close-on-press-escape="false">
            <template #header="{}">
                <!-- 固钉组件，固钉到顶部 -->
                <el-affix :offset="20" style="width: 100%; margin-bottom: 20px">
                    <!-- 指定 flex 布局， 高度为 10， 背景色为白色 -->
                    <div class="flex h-10 bg-white">
                        <div class="mr-auto flex">
                            <el-button @click="isArticleUpdateEditorShow = false" type="warning">
                                <el-icon class="ml-1">
                                    <ArrowLeft />
                                </el-icon>
                                文章管理
                            </el-button>
                        </div>
                        <!-- 字体加粗 -->
                        <h1 class="font-bold" style="justify-items: center; font-size: 20px;">修改文章</h1>
                        <!-- 靠右对齐 -->
                        <div class="ml-auto flex">
                            <el-button type="primary" @click="updateArticleSubmit">
                                <el-icon class="mr-1">
                                    <Promotion />
                                </el-icon>
                                更新文章
                            </el-button>
                        </div>
                    </div>
                </el-affix>
            </template>
            <div style="margin-top: 10px;">
                <!-- label-position="top" 用于指定 label 元素在上面 -->
                <el-form :model="updateArticleForm" ref="updateArticleFormRef" label-position="top" size="large"
                    :rules="rules">
                    <el-form-item label="标题" prop="title">
                        <el-input v-model="updateArticleForm.title" autocomplete="off" size="large" maxlength="40"
                            show-word-limit clearable />
                    </el-form-item>
                    <el-form-item label="内容" prop="content">
                        <!-- Markdown 编辑器 -->
                        <MdEditor v-model="updateArticleForm.content" @onUploadImg="onUploadImg" :previewTheme="mdPreviewTheme"
                            editorId="updateArticleEditor" @onSave="onSave" />
                    </el-form-item>
                    <el-form-item label="封面" prop="cover">
                        <el-upload class="avatar-uploader" action="#" :on-change="handleUpdateCoverChange"
                            :auto-upload="false" :show-file-list="false">
                            <img v-if="updateArticleForm.cover" :src="updateArticleForm.cover" class="avatar" />
                            <el-icon v-else class="avatar-uploader-icon">
                                <Plus />
                            </el-icon>
                        </el-upload>
                    </el-form-item>
                    <el-form-item label="摘要" prop="summary">
                        <!-- :rows="3" 指定 textarea 默认显示 3 行 -->
                        <el-input v-model="updateArticleForm.summary" :rows="3" type="textarea" placeholder="请输入文章摘要" />
                    </el-form-item>
                    <el-form-item label="分类" prop="categoryId">
                        <el-select v-model="updateArticleForm.categoryId" clearable placeholder="---请选择---"
                            size="large" style="width: 200px;">
                            <el-option v-for="item in categories" :key="item.value" :label="item.label"
                                :value="item.value" />
                        </el-select>
                    </el-form-item>
                    <el-form-item label="标签" prop="tags">
                        <span class="w-80">
                            <!-- 标签选择 -->
                            <el-select v-model="updateArticleForm.tags" multiple filterable remote reserve-keyword
                                placeholder="请输入文章标签" remote-show-suffix allow-create default-first-option
                                :remote-method="remoteMethod" :loading="tagSelectLoading" size="large" tag-type="success">
                                <el-option v-for="item in tags" :key="item.value" :label="item.label"
                                    :value="item.value" />
                            </el-select>
                        </span>
                    </el-form-item>
                </el-form>
            </div>
            <!-- {{ updateArticleForm.tags }}
            {{ tags }} -->
        </el-dialog>
    </div>
</template>

<script setup>
// 引入所需图标
import { Search, RefreshRight, Upload, EditPen, ArrowLeft } from '@element-plus/icons-vue'
import { dateEquals } from 'element-plus';
import moment from 'moment';
import { ref, reactive, nextTick, watch } from 'vue';

//表格数据加载动画
const tableLoading = ref(false)

// 分页查询的分类名称
const searchArticleName = ref('')
// 日期
const pickDate = ref('')

//起始时间
const startDate = reactive({})
//结束时间
const endDate = reactive({})
//监听日期组件改变事件，并将开始结束时间设置到变量中
const datepickerChange = (e) => {
    startDate.value = moment(e[0]).format('YYYY-MM-DD')
    endDate.value = moment(e[1]).format('YYYY-MM-DD')
    console.log("开始时间：" + startDate.value + " 结束时间：" + endDate.value)
}

//近期时间
const shortcuts = [
    {
        text: '最近一天',
        value: () => {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 1000 * 3600 * 24 * 1)
            return [start, end]
        }
    },
    {
        text: '最近三天',
        value: () => {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 1000 * 3600 * 24 * 3)
            return [start, end]
        }
    },
    {
        text: '最近一周',
        value: () => {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 1000 * 3600 * 24 * 7)
            return [start, end]
        }
    },
    {
        text: '最近一个月',
        value: () => {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 1000 * 3600 * 24 * 30)
            return [start, end]
        }
    },
    {
        text: '最近三个月',
        value: () => {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 1000 * 3600 * 24 * 90)
            return [start, end]
        }
    },
    {
        text: '最近六个月',
        value: () => {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 1000 * 3600 * 24 * 180)
            return [start, end]
        }
    },
    {
        text: '最近一年',
        value: () => {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 1000 * 3600 * 24 * 365)
            return [start, end]
        }
    }
]

import { publishArticle, getArticlePageList, deleteArticle, viewArticle, updateArticle, autoSaveArticle } from '@/api/admin/article';
import { showMessage, showModel } from '@/composables/utils';
// 引入md - editor - v3编辑器
import { MdEditor } from 'md-editor-v3';
import 'md-editor-v3/lib/style.css'
import { uploadFile } from '@/api/admin/file';
import { getCategoryList } from '@/api/admin/category';
import { getTagSelectList, searchLikeTagName } from '@/api/admin/tag';
import { useRouter } from 'vue-router';

//路由
const router = useRouter()

// md编辑器预览样式
const mdPreviewTheme = ref("smart-blue")

// 表格数据         
const tableData = ref([])
// 当前页码，给了一个默认值 1
const current = ref(1)
// 总数据量，给了个默认值 0
const total = ref(0)
// 每页显示的数据量，给了个默认值 10
const size = ref(10)
 // 每页展示数量变更事件
 const handleSizeChange = (chooseSize) => {
    size.value = chooseSize
    getTableData()
}
//获取分页数据
function getTableData() {
    //显示表格loading
    tableLoading.value = true
    //调用后台接口，传入所需参数
    const reqParams = {
        current: current.value,
        size: size.value,
        startDate: startDate.value,
        endDate: endDate.value,
        title: searchArticleName.value
    }
    getArticlePageList(reqParams).then((res) => {
        if (res.success == true) {
            //获取数据成功
            console.log('获取文章列表')
            tableData.value = res.data
            current.value = res.pageIndex
            size.value = res.size
            total.value = res.total
            
        }
    }).finally(() => {tableLoading.value = false})
}

//重置
function reset() {
    searchArticleName.value = ''
    pickDate.value = ''
    startDate.value = null
    endDate.value = null
}
//进入页面获取数据
getTableData()

//添加分类名
//会话框状态
const isArticlePublishEditorShow = ref(false)
// 发布文章表单引用
const publishArticleFormRef = ref(null)

// 表单对象
const form = reactive({
    id: null,
    title: '',
    content: '请输入内容',
    cover: '',
    categoryId: null,
    tags: [],
    summary: ""
})

// 监听content 发生变化就触发md编辑器保存todo

// 表单校验规则
const rules = {
    title: [
        { required: true, message: '请输入文章标题', trigger: 'blur' },
        { min: 1, max: 40, message: '文章标题要求大于1个字符，小于40个字符', trigger: 'blur' },
    ],
    content: [{ required: true }],
    cover: [{ required: true }],
    categoryId: [{ required: true, message: '请选择文章分类', trigger: 'blur' }],
    tags: [{ required: true, message: '请选择文章标签', trigger: 'blur' }],
}

// 上传封面
function handleCoverChange(file) {
    // 表单对象
    let formData = new FormData()
    // 添加file字段
    formData.append('file', file.raw)
    // 上传图片
    uploadFile(formData).then((res) => {
        if (res.success == true) {
            // 图片上传成功
            form.cover = res.data.url
            showMessage("文章封面上传成功！")
        } else {
            let message = res.message
            showMessage("message", 'error')
        } 

    })
}

// 上传md编辑器中的图片
const onUploadImg = async (files, callback) => {
    const res = await Promise.all(
        files.map((file) => {
            return new Promise((rev, rej) => {
                console.log("markdown 编辑器开始上传文件")
                let formData = new FormData()
                formData.append('file', file)
                uploadFile(formData).then((res) => {
                    console.log(res)
                    console.log("访问路径：" + res.data.url)
                    // 通过callback函数，显示上传图片
                    callback([res.data.url])
                })
            })
        })
    )
}

// 保存
const onSave = (v, h) => {
    // console.log(v);

    // 保存数据
    
    // autoSaveArticle()

//   h.then((html) => {
//     console.log(html);
//   });
}

const categories = ref([])

// 获取分类列表
const getCategories = () => {
    getCategoryList().then((res) => {
        if (res.success == true) {
            categories.value = res.data
        } else {
            showMessage("分类专栏列表获取异常", "error")
        }
    })
}
// 获取分类列表
getCategories()

const tags = ref([])
//获取标签列表
const getTags = () => {
    getTagSelectList().then((res) => {
        if (res.success == true) {
            tags.value = res.data
        } else {
            showMessage("标签列表获取异常", "error")
        }
    })
}
getTags()

//模糊查询标签
const tagSelectLoading = ref(false)
const remoteMethod = (query) => {
    console.log("标签远程搜索：" + tags.value)
    
    if (query) {
        // 显示加载动画
        tagSelectLoading.value = true
        // 构造查询对象
        let params = {"key": query}
        // 调用模糊查询接口
        searchLikeTagName(params).then((res) => {
            if (res.success == true) {
                tags.value = res.data
            }
        }).finally(() => {tagSelectLoading.value = false})
    }
}

// 发布文章
const publishArticleSubmit = () => {
    console.log("提交文章内容" + form.content)
    // 校验表单
    publishArticleFormRef.value.validate((valid) => {
        if (!valid) {
            console.log("文章提交表单格式异常")
            return false
        }

        publishArticle(form).then((res) => {
            if (res.success == true) {
                showMessage("发布成功！")
                // 隐藏发布文章对话框
                isArticlePublishEditorShow.value = false
                // 将form表单置空
                form.title = ''
                form.content = ''
                form.cover = ''
                form.summary = ''
                form.categoryId = null
                form.tags = []
                //重新获取数据
                getTableData()
            } else {
                let message = res.message
                showMessage(message, 'error')
            }
        })
    })
}

// 是否显示编辑文章对话框
const isArticleUpdateEditorShow = ref(false)
// 编辑文章表单引用
const updateArticleFormRef = ref(null)

// 修改文章表单对象
const updateArticleForm = reactive({
    id: null,
    title: '',
    content: '请输入内容',
    cover: '',
    categoryId: null,
    tags: [],
    summary: ""
})

// 点击编辑按钮
const showArticleUpdateEditor = (row) => {
    // 显示修改文章对话框
    isArticleUpdateEditorShow.value = true

    //获取文章id
    let articleId = row.id
    let params = {
        "id": articleId
    }
    console.log(params)
    // 获取文章详情
    viewArticle(params).then((res) => {
        if (res.success == true) {
            // 设置表单数据
            updateArticleForm.id = res.data.id
            updateArticleForm.title = res.data.title
            updateArticleForm.cover = res.data.cover
            updateArticleForm.content = res.data.content
            updateArticleForm.categoryId = res.data.categoryId
            updateArticleForm.summary = res.data.summary
            updateArticleForm.tags = res.data.tagIds
        } else {
            let message = res.message
            showMessage(message, 'error')
        }
    })
}

// 更新文章
const updateArticleSubmit = () => {
    console.log("更新文章内容" + form.content)
    // 校验表单
    updateArticleFormRef.value.validate((valid) => {
        if (!valid) {
            console.log("文章提交表单格式异常")
            return false
        }

        updateArticle(updateArticleForm).then((res) => {
            if (res.success == true) {
                showMessage("更新成功！")
                // 隐藏发布文章对话框
                isArticleUpdateEditorShow.value = false
                // 将form表单置空
                updateArticleForm.title = ''
                updateArticleForm.content = ''
                updateArticleForm.cover = ''
                updateArticleForm.summary = ''
                updateArticleForm.categoryId = null
                updateArticleForm.tags = []
                //重新获取数据
                getTableData()
            } else {
                let message = res.message
                showMessage(message, 'error')
            }
        })
    })
}

// 编辑文章：上传文章封面图片
const handleUpdateCoverChange = (file) => {
    // 表单对象
    let formData = new FormData()
    // 添加 file 字段，并将文件传入 
    formData.append('file', file.raw)
    uploadFile(formData).then((e) => {
        // 响参失败，提示错误消息
        if (e.success == false) {
            let message = e.message
            showMessage(message, 'error')
            return
        }

        // 成功则设置表单对象中的封面链接，并提示上传成功
        updateArticleForm.cover = e.data.url
        showMessage('上传成功')
    })
}

//删除对应的文章
function deleteArticleSubmit(row) {
    //获取对应的id
    console.log(row)
    let id = row.id;

    showModel("是否确认删除文章：" + row.title, "warning", "温馨提示：").then(() => {
        //发送删除请求
        deleteArticle({ id: id }).then((res) => {
            if (res.success == true) {
                let message = "标题为" + row.title + "的文章已删除！"
                console.log(message)
                showMessage(message)
                //刷新数据
                getTableData()
            } else {
                let message = res.message
                showMessage(message, 'warning')
            }
        })

    }).catch(() => {
        let message = "删除文章操作已取消！删除文章标题为：" + row.title
        showMessage(message, 'error')
    })

}

// 跳转到文章详情页
const goArticleDetailPage = (id) => {
    router.push({path: '/article/detail/' + id})
}
</script>

<style scoped>
/* 封面图片样式 */
.avatar-uploader .avatar {
    width: 200px;
    height: 100px;
    display: block;
}

.el-icon.avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 200px;
    height: 100px;
    text-align: center;
}
/* ::v-deep是vue3提供的深度选择器，.el-form-item__label是element-plus官方定义的类 */
::v-deep .el-form-item__label{
  font-weight: bold;
  font-size: 16px;
}
</style>

<style>
.md-editor-footer {
    height: 40px;
    font-size: 14px;
    font-weight: bolder;
}
</style>